#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <assert.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/epoll.h>
#include <signal.h>
#include <sys/wait.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>

class cgi
{
	public:
		cgi(){}
		~cgi(){}
		void init(int epollfd,int sockfd,const sockaddr_in & client_addr)
		{
			m_epollfd=epollfd;
			m_sockfd=sockfd;
			m_address=client_addr;
			memset(m_buf,'\0',BUFFER_SIZE);
			m_read_idx=0;
		}

		void process();
	private:
		static const int BUFFER_SIZE =1024;
		static int m_epollfd;
		int m_sockfd;
		sockaddr_in m_address;
		char m_buf[BUFFER_SIZE];
		int m_read_idx;


		char * get_file_name(char * buf)
		{
			char *loc;
			loc=strpbrk(buf," \t");
			loc++;
			loc++;
			char * end;
			end=strpbrk(loc," \t");
			*end='\0';
			return loc;
		}

};

int cgi::m_epollfd=-1;

void cgi::process()
{
	int idx = 0;
	int ret=-1;
	while( true )
	{
	    idx = m_read_idx;

	    ret = recv( m_sockfd, m_buf + idx, BUFFER_SIZE-1-idx, 0 );
	    if( ret < 0 )
	    {
		if( errno != EAGAIN )
		{
		    epoll_ctl( m_epollfd, EPOLL_CTL_DEL, m_sockfd, 0 );
		    close( m_sockfd );
		}
		break;
	    }
	    else if( ret == 0 )
	    {
		epoll_ctl( m_epollfd, EPOLL_CTL_DEL, m_sockfd, 0 );
		close( m_sockfd );
		break;
	    }
	    else
	    {
		m_read_idx += ret;
		printf( "user content is: %s\n", m_buf );
		//idx = m_read_idx;
		for(;idx<m_read_idx;++idx)
		{
			if( ( idx < 2 ) || ( m_buf[idx-2] != '\r' ) || ( m_buf[idx-1] != '\n' ) )
			{
			    break;
			}
		}

		if(idx==m_read_idx)
		{
			continue;
		}
		m_buf[idx-1]='\0';

		char* file_name = m_buf;
		file_name=get_file_name(file_name);
		printf("file name  %s\n",file_name);
		printf("file access %d\n",access( file_name, F_OK ) );
		if( access( file_name, F_OK ) == -1 )
		{
		    epoll_ctl( m_epollfd, EPOLL_CTL_DEL, m_sockfd, 0 );
		    close( m_sockfd );
		    break;
		}
		ret = fork();
		if( ret == -1 )
		{
		    epoll_ctl( m_epollfd, EPOLL_CTL_DEL, m_sockfd, 0 );
		    close( m_sockfd );
		    break;
		}
		else if( ret > 0 )
		{
		    epoll_ctl( m_epollfd, EPOLL_CTL_DEL, m_sockfd, 0 );
		    close( m_sockfd );
		    break;
		}
		else
		{
		    printf("%s\n",m_buf);
		    close( STDOUT_FILENO );
		    dup( m_sockfd );
		    //execl( users[sockfd].buf, users[sockfd].buf, 0 );
		    execl( file_name, file_name, 0 );
		    exit( 0 );
		}
	    }
	}

}

